package ddz.utils;

import com.kaka.util.Charsets;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class AES {

    private AES() {
    }

    /**
     * 加密
     *
     * @param src      byte[] 加密的数据源
     * @param password byte[] 加密秘钥
     * @return byte[] 加密后的数据
     */
    public static byte[] encrypt(byte[] src, byte[] password) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(password, "AES");
            //Cipher对象实际完成加密操作
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            //ECB模式下，iv不需要
            IvParameterSpec iv = new IvParameterSpec(password);
            //用密匙初始化Cipher对象
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            //现在，获取数据并加密
            //正式执行加密操作
            return cipher.doFinal(src);
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException ex) {
            Logger.getLogger(DES.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * 加密
     *
     * @param src      byte[] 加密的数据源
     * @param password String 加密秘钥
     * @return byte[] 加密后的数据
     */
    public static byte[] encrypt(byte[] src, String password) {
        byte[] keyBytes = password.getBytes(Charsets.utf8);
        return encrypt(src, keyBytes);
    }

    /**
     * 解密
     *
     * @param src      byte[] 解密的数据源
     * @param password byte[] 解密秘钥
     * @return byte[] 解密后的数据
     */
    public static byte[] decrypt(byte[] src, byte[] password) {
        try {
            SecretKeySpec keySpec = new SecretKeySpec(password, "AES");
            // Cipher对象实际完成解密操作，CBC为加密模式，
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            //ECB模式下，iv不需要
            IvParameterSpec iv = new IvParameterSpec(password);
            // 用密匙初始化Cipher对象
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            // 真正开始解密操作
            return cipher.doFinal(src);
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException ex) {
            Logger.getLogger(DES.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * 解密
     *
     * @param src        byte[] 解密的数据源
     * @param password   String 解密秘钥
     * @param psdCharset 秘钥字符编码
     * @return byte[] 解密后的数据
     */
    public static byte[] decrypt(byte[] src, String password, Charset psdCharset) {
        byte[] keyBytes = password.getBytes(psdCharset);
        return decrypt(src, keyBytes);
    }

    /**
     * 解密
     *
     * @param src      byte[] 解密的数据源
     * @param password String 解密秘钥
     * @return byte[] 解密后的数据
     */
    public static byte[] decrypt(byte[] src, String password) {
        return decrypt(src, password, Charsets.utf8);
    }

}
